package org.zhang.core.asm;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.zhang.core.track.CallContext;
import org.zhang.core.track.Span;
import org.zhang.core.util.JacksonUtil;

import java.util.concurrent.atomic.AtomicInteger;

public class ProfilingAspect {
    // ANSI 转义码
    static String reset = "\u001B[0m";
    static String red = "\u001B[31m";
    static String blue = "\033[1;94m";
    static String green = "\u001B[32m";
    static String cyan = "\u001B[96m";
    static AtomicInteger number = new AtomicInteger(0);

    public synchronized static void point(String className, String methodName, long duration, String lineNumber,
                                          String[] paramTypes, Object[] parameters,
                                          String returnType, String span, Object returnValue) throws JsonProcessingException {
        int currentNumber = number.incrementAndGet();
        printSectionHeader("监控 - Begin" + currentNumber);
        printInfo("链路id", CallContext.getTrace());
        printInfo("线程名", Thread.currentThread().getName());
        printInfo("层级", span);
//        printInfo("测试层级", CallContext.getCurrentSpan() != null ? CallContext.getCurrentSpan().toString() : null);
        printInfo("类名", className);
        printInfo("方法", methodName);
        printInfo("入参类型", JacksonUtil.toJson(paramTypes));
        printInfoWithExceptionHandling("入参[值]", () -> JacksonUtil.toJson(parameters));
        printInfo("出参类型", returnType);
        printInfoWithExceptionHandling("出参[值]", () -> JacksonUtil.toJson(returnValue));
        printInfo("耗时", duration + "ms");
        printInfo("执行行号", lineNumber);
        printSectionFooter("监控 - End" + currentNumber);
    }

    private static void printSectionHeader(String header) {
        System.out.println("╔═══════════════════════════════════════════╗");
        System.out.println("║           " + blue + header + reset);
    }

    private static void printSectionFooter(String footer) {

        System.out.println("║           " + blue + footer + reset);
        System.out.println("╚═══════════════════════════════════════════╝\n");
    }

    private static void printInfo(String label, String value) {
        System.out.println("║ " + green + label + reset + ": " + value);
    }

    private static void printInfoWithExceptionHandling(String label, ThrowingFunction<String> valueProvider) {
        try {
            String value = valueProvider.apply();
            printInfo(label, value);
        } catch (Exception e) {
            System.out.println("║ " + red + label + "打印失败" + reset + ": " + e.getMessage());
        }
    }

    @FunctionalInterface
    interface ThrowingFunction<T> {
        T apply() throws Exception;
    }

    //方法开始时执行
    public static String before() {
        Span entrySpan = CallContext.createEntrySpan();
        CallContext.setTrace();
        return entrySpan.toString();
    }

    //请求开始执行
    public static void init() {
        CallContext.removeTrace();
        CallContext.removeSpan();
    }
}
